package com.vogue.supplymall.order.controller;

import com.vogue.supplymall.common.domain.dto.ControllerResultInfo;
import com.vogue.supplymall.common.domain.dto.MultiOrderInfo;
import com.vogue.supplymall.common.domain.dto.OrderInfo;
import com.vogue.supplymall.common.domain.dto.UserInfo;
import com.vogue.supplymall.common.domain.tool.MessageSourceUtils;
import com.vogue.supplymall.order.common.CheckOrderUtils;
import com.vogue.supplymall.order.domain.biz.OrderBiz;
import com.vogue.supplymall.order.domain.service.OrderItemProductService;
import com.vogue.supplymall.order.domain.service.OrderItemService;
import com.vogue.supplymall.order.domain.service.OrderService;
import com.vogue.supplymall.order.exception.AddOrderException;
import com.vogue.supplymall.order.exception.DifferentOrderException;
import com.vogue.supplymall.order.exception.OrderPriceException;
import com.vogue.supplymall.order.exception.SendAmountException;
import com.vogue.supplymall.order.exception.UpdateOrderException;
import com.vogue.supplymall.order.exception.ConfirmOrderItemCheckException;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * The type Order controller.
 *
 * @aouthor: zhangliang
 * @date: Create in 2018-01-09
 */
@RestController
public class OrderController extends BaseController {
    /**
     * The constant log.
     */
    public static final Logger log = LoggerFactory.getLogger(OrderController.class);

    @Resource
    private OrderBiz orderBiz;
    @Resource
    private OrderService orderService;
    @Resource
    private OrderItemService orderItemService;
    @Resource
    private OrderItemProductService orderItemProductService;
    @Resource
    private MessageSourceUtils messageSourceUtils;

    /**
     * Confirm order response entity.
     * 购物车中去结算按钮--订单确认画面
     *
     * @param appver    the appver
     * @param orderInfo the order info
     * @return the response entity
     */
    @RequestMapping(value = "/is/{appver}/order/confirm", method = RequestMethod.POST)
    public ResponseEntity<Object> confirmOrder(@PathVariable("appver") String appver, @RequestBody OrderInfo orderInfo) {
        log.info("confirm order start >>>>>> ");
        UserInfo info = new UserInfo();
        if (SecurityUtils.getSubject().isAuthenticated()) {
            info = (UserInfo) SecurityUtils.getSubject().getPrincipal();
            log.info("获取登信息：" + info.getLoginId());
            if (CheckOrderUtils.checkConfirmOrderParameter(orderInfo, info.getLoginUserType())) {
                log.info(" 参数错误！ ");
                throw new AddOrderException(orderInfo.getGroupName() + "-" + orderInfo.getShopName());
            }
        } else {
            log.info("获取登信息失败！");
        }

        ControllerResultInfo resultInfo = new ControllerResultInfo();
        resultInfo.setResult(true);
        Map<String, Object> data = new HashMap<>();
        try {
            data = orderBiz.findOrder(orderInfo, info);
        } catch (ConfirmOrderItemCheckException e) {
            log.info(" method addCart() throw exception, cause: Submit order check item Units need the same ");
            throw e;
        }
        resultInfo.setData(data);
        log.info(" <<<<<< confirm order end");
        return new ResponseEntity<>(resultInfo, HttpStatus.OK);
    }

    /**
     * Confirm multi order response entity.
     * 购物车中去结算按钮--订单确认画面
     * 一次提交多个订单
     *
     * @param appver         the appver
     * @param multiOrderInfo the multi order info
     * @return response entity
     */
    @RequestMapping(value = "/is/{appver}/order/confirmMulti", method = RequestMethod.POST)
    public ResponseEntity<Object> confirmMultiOrder(@PathVariable("appver") String appver, @RequestBody MultiOrderInfo multiOrderInfo) {
        log.info("confirm Multi order start >>>>>> ");
        UserInfo info = new UserInfo();
        List<OrderInfo> orderInfos = multiOrderInfo.getShopData();
        if (SecurityUtils.getSubject().isAuthenticated()) {
            info = (UserInfo) SecurityUtils.getSubject().getPrincipal();
            log.info("获取登信息：" + info.getLoginId());
            for (OrderInfo orderInfo : orderInfos) {
                if (CheckOrderUtils.checkConfirmOrderParameter(orderInfo, info.getLoginUserType())) {
                    log.info(" 参数错误！ ");
                    throw new AddOrderException(orderInfo.getGroupName() + "-" + orderInfo.getShopName() + "参数错误！");
                }
            }
        } else {
            log.info("获取登信息失败！");
        }

        ControllerResultInfo resultInfo = new ControllerResultInfo();
        resultInfo.setResult(true);
        List<Map<String, Object>> data = new ArrayList<>();
        BigDecimal orderprice = BigDecimal.ZERO;
        for (OrderInfo orderInfo : orderInfos) {
            Map<String, Object> result = new HashMap<>();
            try {
                result = orderBiz.findOrder(orderInfo, info);
            } catch (ConfirmOrderItemCheckException e) {
                log.info(" method addCart() throw exception, cause: Submit order check item Units need the same ");
                throw e;
            }
            BigDecimal price = (BigDecimal) result.get("orderprice");
            orderprice = orderprice.add(price);
            data.add(result);
        }
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("orderprice", orderprice);
        dataMap.put("shopData", data);
        resultInfo.setData(dataMap);
        log.info(" <<<<<< confirm Multi order end");
        return new ResponseEntity<>(resultInfo, HttpStatus.OK);
    }

    /**
     * Add order response entity.
     * 订单确认画面提交订单按钮
     *
     * @param appver    the appver
     * @param orderInfo the order info
     * @return the response entity
     */
    @RequestMapping(value = "/is/{appver}/order/add", method = RequestMethod.POST)
    public ResponseEntity<Object> addOrder(@PathVariable("appver") String appver, @RequestBody OrderInfo orderInfo) {
        log.info("add order start >>>>>> ");
        UserInfo info = new UserInfo();
        if (SecurityUtils.getSubject().isAuthenticated()) {
            info = (UserInfo) SecurityUtils.getSubject().getPrincipal();
            log.info("获取登信息：" + info.getLoginId());
            if (CheckOrderUtils.checkAddOrderParameter(orderInfo, info.getLoginUserType())) {
                log.info(" 参数错误！ ");
                throw new AddOrderException("参数错误！");
            }
        } else {
            log.info("获取登信息失败！");
        }

        Map<String, Long> longMap;
        try {
            longMap = orderBiz.addOrder(orderInfo, info);
        } catch (SendAmountException ex) {
            log.info(" method addOrder() throw SendAmountException, Insufficient Send Amount");
            throw new SendAmountException(ex.getArgs()[0], ex.getArgs()[1]);
        } catch (OrderPriceException ex) {
            log.info(" method addOrder() throw OrderPriceException, Order Price Exception");
            throw new OrderPriceException("");
        } catch (DifferentOrderException ex) {
            log.info(" method addOrder() throw DifferentOrderException, Different Order Exception");
            throw new DifferentOrderException(ex.getArgs()[0], ex.getArgs()[1]);
        } catch (UpdateOrderException ex) {
            log.info(" method addOrder() throw AddOrderException, add order failed");
            throw new AddOrderException(ex.getArgs()[0]);
        } catch (RuntimeException ex) {
            log.info(" method addOrder() throw AddOrderException, add order failed");
            throw new AddOrderException("");
        }

        ControllerResultInfo resultInfo = new ControllerResultInfo();
        resultInfo.setResult(true);
        resultInfo.setData(longMap);
        /* 返回订单提交成功 */
        resultInfo.setMsg(messageSourceUtils.getMessage("2608", new String[]{}));
        log.info(" <<<<<< add order end");
        return new ResponseEntity<>(resultInfo, HttpStatus.OK);
    }


    /**
     * Add order response entity.
     * 订单确认画面提交订单按钮
     * 一次提交多个订单
     *
     * @param appver         the appver
     * @param multiOrderInfo the multi order info
     * @return the response entity
     */
    @RequestMapping(value = "/is/{appver}/order/addMulti", method = RequestMethod.POST)
    public ResponseEntity<Object> addMultiOrder(@PathVariable("appver") String appver, @RequestBody MultiOrderInfo multiOrderInfo) {
        log.info("add Multi order start >>>>>> ");
        UserInfo info = new UserInfo();
        List<OrderInfo> orderInfos = multiOrderInfo.getShopData();
        if (SecurityUtils.getSubject().isAuthenticated()) {
            info = (UserInfo) SecurityUtils.getSubject().getPrincipal();
            log.info("获取登信息：" + info.getLoginId());
            for (OrderInfo orderInfo : orderInfos) {
                orderInfo.setAddress(multiOrderInfo.getAddress());
                if (CheckOrderUtils.checkAddOrderParameter(orderInfo, info.getLoginUserType())) {
                    log.info(" 参数错误！ ");
                    throw new AddOrderException(orderInfo.getGroupName() + "-" + orderInfo.getShopName() + "参数错误！");
                }
            }
        } else {
            log.info("获取登信息失败！");
        }

        List<Map<String, Long>> data;
        try {
            data = orderBiz.addMultiOrder(orderInfos, info);
        } catch (SendAmountException ex) {
            log.info(" method addOrder() throw SendAmountException, Insufficient Send Amount");
            throw new SendAmountException(ex.getArgs()[0], ex.getArgs()[1]);
        } catch (OrderPriceException ex) {
            log.info(" method addOrder() throw OrderPriceException, Order Price Exception");
            throw new OrderPriceException("");
        } catch (DifferentOrderException ex) {
            log.info(" method addOrder() throw DifferentOrderException, Different Order Exception");
            throw new DifferentOrderException(ex.getArgs()[0], ex.getArgs()[1]);
        } catch (UpdateOrderException ex) {
            log.info(" method addOrder() throw UpdateOrderException, add order failed");
            throw new AddOrderException(ex.getArgs()[0]);
        } catch (RuntimeException ex) {
            log.info(" method addOrder() throw RuntimeException, add order failed");
            throw new AddOrderException("");
        }

        ControllerResultInfo resultInfo = new ControllerResultInfo();
        resultInfo.setResult(true);
        resultInfo.setData(data);
        /* 返回订单提交成功 */
        resultInfo.setMsg(messageSourceUtils.getMessage("2608", new String[]{}));
        log.info(" <<<<<< add Multi order end");
        return new ResponseEntity<>(resultInfo, HttpStatus.OK);
    }
}
